// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

#nullable enable

using System;
using Newtonsoft.Json;
using NuGet.Protocol.Model;
using NuGet.Versioning;

namespace NuGet.Protocol.Converters
{
    internal class PackageVulnerabilityInfoConverter : JsonConverter<PackageVulnerabilityInfo>
    {
        public override PackageVulnerabilityInfo ReadJson(JsonReader reader, Type objectType, PackageVulnerabilityInfo? existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            Uri? uri = null;
            PackageVulnerabilitySeverity severity = PackageVulnerabilitySeverity.Unknown;
            VersionRange? versionRange = null;

            while (reader.Read() && reader.TokenType != JsonToken.EndObject)
            {
                if (reader.TokenType == JsonToken.PropertyName)
                {
                    string propertyName = (string)reader.Value!;
                    switch (propertyName)
                    {
                        case JsonProperties.Url:
                            reader.Read();
                            uri = serializer.Deserialize<Uri>(reader);
                            break;

                        case JsonProperties.Severity:
                            {
                                int? value = reader.ReadAsInt32();
                                if (value.HasValue && value.Value >= (int)PackageVulnerabilitySeverity.Low && value.Value <= (int)PackageVulnerabilitySeverity.Critical)
                                {
                                    severity = (PackageVulnerabilitySeverity)value.Value;
                                }
                            }
                            break;

                        case JsonProperties.Versions:
                            reader.Read();
                            versionRange = serializer.Deserialize<VersionRange>(reader);
                            break;
                    }
                }
            }

            if (versionRange is null)
            {
                versionRange = new VersionRange(includeMinVersion: false, includeMaxVersion: false);
            }

            return new PackageVulnerabilityInfo(uri!, severity, versionRange);
        }

        public override void WriteJson(JsonWriter writer, PackageVulnerabilityInfo? value, JsonSerializer serializer)
        {
            if (value is null)
            {
                return;
            }

            writer.WriteStartObject();

            writer.WritePropertyName(JsonProperties.Url);
            serializer.Serialize(writer, value.Url);

            //  The NuGet Server API defines severity as a number/integer, so don't write the enum name
            writer.WritePropertyName(JsonProperties.Severity);
            writer.WriteValue((int)value.Severity);

            writer.WritePropertyName(JsonProperties.Versions);
            serializer.Serialize(writer, value.Versions);

            writer.WriteEndObject();
        }
    }
}
